package com.zhuang.taiqiu.netty.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.InvalidProtocolBufferException;
import com.zhuang.taiqiu.config.NettyConfig;
import com.zhuang.taiqiu.config.SessionManage;
import com.zhuang.taiqiu.proto.GameMessageOuterClass.GameMessage;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Service
@ChannelHandler.Sharable
public class MyWebSocketHandler extends SimpleChannelInboundHandler<WebSocketFrame> {

    private final Logger LOGGER = LoggerFactory.getLogger(getClass());

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, WebSocketFrame webSocketFrame) throws Exception {
        handWebsocketFrame(channelHandlerContext, webSocketFrame);
    }

    /**
     * 处理客户端与服务端之间的业务
     * @param ctx
     * @param frame
     */
    private void handWebsocketFrame(ChannelHandlerContext ctx,WebSocketFrame frame) throws Exception {
        if(frame instanceof CloseWebSocketFrame) {
            ctx.channel().close();
        }

//        判断是否时ping消息
        if(frame instanceof PingWebSocketFrame) {
            ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
        }

        if(!(frame instanceof BinaryWebSocketFrame)){
            LOGGER.warn("接收到的不是protobuf数据");
            return;
        }

        BinaryWebSocketFrame binaryWebSocketFrame = (BinaryWebSocketFrame)frame;
        ByteBuf content = binaryWebSocketFrame.content();

        // 将ByteBuf内容复制到一个新的字节数组
        byte[] bytes = new byte[content.readableBytes()];
        content.getBytes(content.readerIndex(), bytes);

        // 解码protobuf消息
        GameMessage gameMessage = GameMessage.parseFrom(bytes);
        ctx.fireChannelRead(gameMessage);



//        TextWebSocketFrame textWebSocketFrame = (TextWebSocketFrame) frame;
//        ByteBuf bytebuf = textWebSocketFrame.content();
////从content中写入缓冲区
//        String content = bytebuf.toString(Charset.forName("utf-8"));
//        logger.info(content);
//        JSONObject jsonObject = JSONObject.parseObject(content);
////将json字符串转变为json对象
//        logger.info(content);
////从json对象中按属性取值
//        Byte type = jsonObject.getByte("type");
//        JSONObject parmas = jsonObject.getJSONObject("params");
//        Packet packet = null;
//
//        switch (type) {
//            // 注册user-->channel 映射
//            case 7:
//                RegisterPacket registerRequestPacket = new RegisterPacket();
////                将json对象转换为实体类
//                User user =  JSON.parseObject(parmas.toJSONString(), User.class);
//                registerRequestPacket.setUser(user);
//                packet = registerRequestPacket;
//                break;
//            // 单聊
//            case 1:
//                SingleMessagePacket messageRequestPacket = new SingleMessagePacket();
//                messageRequestPacket.setMessage(parmas.getString("message"));
//                messageRequestPacket.setToUserId(parmas.getString("toMessageId"));
//                messageRequestPacket.setFileType(parmas.getString("fileType"));
//                packet = messageRequestPacket;
//                break;
//            // 创建群聊
//            case 3:
//                CreateGroupPacket createGroupPacket = new CreateGroupPacket();
//                String userListStr = parmas.getString("userIdList");
//                log.info(userListStr);
//                List<String> userIdList = Arrays.asList(userListStr.split(","));
//                log.info(userIdList.toString());
//                createGroupPacket.setUserIdList(userIdList);
//                createGroupPacket.setGroupId(parmas.getInteger("groupId"));
//                packet = createGroupPacket;
//                break;
//            // 群聊消息
//            case 9:
//                GroupMessagePacket groupMessageRequestPacket = new GroupMessagePacket();
//                groupMessageRequestPacket.setMessage(parmas.getString("message"));
//                groupMessageRequestPacket.setToGroupId(parmas.getInteger("toMessageId"));
//                groupMessageRequestPacket.setFileType(parmas.getString("fileType"));
//                packet = groupMessageRequestPacket;
//                break;
//            //心跳检测 暂未添加
//            default:
//                break;
//        }
//
//        //        返回应答消息
////        获取客户端向服务端发送的消息
//        if(type == commond.SINGLE_MESSAGE||type == commond.GROUP_MESSAGE){
//            ByteBuf buf = getByteBuf(ctx, parmas.getString("message"));
//            TextWebSocketFrame tws = new TextWebSocketFrame(buf);
//            ctx.writeAndFlush(tws);
//        }
//
////        log.info(packet.getCommand());
//

    }


    //客户端与服务端创建连接
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        NettyConfig.group.add(ctx.channel());
        log.info("channelActive客户端与服务端连接开启....");
    }

    //客户端与服务端断开连接
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Object userId = ctx.channel().attr(AttributeKey.valueOf("userId")).get();
        if(null != userId){
            SessionManage.clearChannel((Long) userId);
        }
        //删除缓存的hashmap
        NettyConfig.group.remove(ctx.channel());
        log.info("channelInactive客户端与服务端连接关闭....");
    }

    //接收结束之后 read相对于服务端
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    //    出现异常时调用
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

}
